﻿/******************************************************
* author :  cwj
* email  :  chenwenji_360@live.com 
* history:  created by cwj 2015/8/19 18:00:05 
* clrversion :4.0.30319.42000
******************************************************/

using Machine.DataAccess.Linq;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;

namespace Machine.DataAccess.Operation
{
    class DatabaseCreator
    {
        private static object _sync = new object();

        private ProviderElement CreateProvider(string databaseName,string connectionString)
        {
            if (databaseName == null) throw new ArgumentNullException("数据库名字不能为空");
            var manager = Config.Instance.Manager;
            if (manager == null) throw new ArgumentNullException("配置文件出错");
            if (manager.Provider == "System.Data.SQLite") throw new NotSupportedException("暂时不支持Sqlite的动态创建");
            var providerElement = new ProviderElement();
            providerElement.ConnectionString = connectionString;//string.Format(manager.ConnectionString, manager.UserName, manager.PassWork, databaseName);
            providerElement.IsCodeFirst = true;
            providerElement.Provider = manager.Provider;
            providerElement.Key = databaseName;
            return providerElement;
        }

        private ProviderElement MainProviderElement
        {
            get
            {
                ProviderElement providerElement = null;
                var manage = Config.Instance.Manager;
                switch (manage.Provider)
                {
                    case "System.Data.SqlClient":
                        throw new NotSupportedException("暂时不支持");
                    case "System.Data.SQLite":
                        throw new NotSupportedException("暂时不支持");
                    case "MySql.Data.MySqlClient":
                        providerElement = CreateProvider("mysql", this.CreateDatabaseString("mysql"));
                        break;
                    default:
                        throw new ArgumentException("异常的数据库提供者");
                }
                return providerElement;
            }
        }

        private static ConcurrentBag<string> databaseCache = new ConcurrentBag<string>();

        private bool DatabaseExtist(ProviderElement providerElement,string databaseName)
        {
            if (databaseCache.Contains(databaseName)) return true;
            string seachSql = null;
            switch (providerElement.Provider)
            {
                case "System.Data.SqlClient":
                    throw new NotSupportedException("暂时不支持");
                case "System.Data.SQLite":
                    throw new NotSupportedException("暂时不支持");
                case "MySql.Data.MySqlClient":
                    //providerElement = CreateProvider("mysql", manage.ConnectionString);
                    seachSql = "SHOW DATABASES";
                    break;
                default:
                    throw new ArgumentException("异常的数据库提供者");
            }
            var databaseNames = new DataReader<string>(new TranslateResult(seachSql, new DbParameter[0]), providerElement,null);
            foreach (var item in databaseNames)
            {
                databaseCache.Add(item);
            }
            return databaseCache.Contains(databaseName);
        }

        public ProviderElement CreateDatabase(string databaseName)
        {
            lock (_sync)
            {
                ProviderElement providerElement = MainProviderElement;
                string createSql = this.CreateDatabaseSQL(databaseName);
                string connectionStr = this.CreateDatabaseString(databaseName);
                var manage = Config.Instance.Manager;
                if (providerElement == null) throw new Exception("创建数据库异常");
                if (!this.DatabaseExtist(providerElement, databaseName))
                    DataResult.CodeFirstExcuteNonQuery(new TranslateResult(createSql, new DbParameter[0]), providerElement);
                return CreateProvider(databaseName, connectionStr);
            }
        }

        private string CreateDatabaseString(string databaseName)
        {
            var manage = Config.Instance.Manager;
            switch (Config.Instance.Manager.Provider)
            {
                case "System.Data.SqlClient":
                    throw new NotSupportedException("暂时不支持");
                case "System.Data.SQLite":
                    throw new NotSupportedException("暂时不支持");
                case "MySql.Data.MySqlClient":
                    return string.Format("server={4};User Id={0};password={1};Database={2};port={3};CharSet=utf8", manage.UserName, manage.PassWork, databaseName, manage.Port, manage.Address);
                default:
                    throw new ArgumentException("异常的数据库提供者");
            }
        }

        private string CreateDatabaseSQL(string databaseName)
        {
            var manage = Config.Instance.Manager;
            switch (Config.Instance.Manager.Provider)
            {
                case "System.Data.SqlClient":
                    throw new NotSupportedException("暂时不支持");
                case "System.Data.SQLite":
                    throw new NotSupportedException("不支持");
                case "MySql.Data.MySqlClient":
                    return string.Format("Create Database `{0}` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci", databaseName);
                default:
                    throw new ArgumentException("异常的数据库提供者");
            }
        }
    }
}
